package org.thread.test05.tx.demo05.t01;

import java.util.LinkedList;

/**
 * 篮子 - 装水果 -- 注意：在此案例中，锁对象就是 this
 *
 * @author ZQX
 * @date 2025-03-14
 */
public class Box {

    /**
     * 篮子容器
     */
    private LinkedList<Fruit> boxList = new LinkedList<>();

    /**
     * 定义常量 - 表达篮子最大容量
     */
    private static final int MAX_SIZE = 5;


    /**
     * 男孩放水果
     *
     * @param name  男孩的姓名
     * @param fruit 水果名称
     */
    public synchronized void put(String name, Fruit fruit) {
        // 情况一：篮子满的情况
        if (boxList.size() == MAX_SIZE) {
            // 通知女孩吃水果
            this.notify();
            try {
                // 男孩停止摘水果 - 进入等待状态 - 注意：wait后面的代码不会往下执行
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // return;
        }

        // 情况二：篮子未满的情况 - 摘水果，并放入到篮子中
        boxList.add(fruit) ;

        // 显示信息
        System.out.printf("当前篮子的容量：[%d]，男孩子：[%s]，摘的水果是：[%s] %n", boxList.size(), name, fruit);

        try {
            // 睡眠 500 毫秒，为了更好地看效果
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 女孩取水果
     *
     * @param name 女孩的名称
     */
    public synchronized void take(String name) {
        // 情况一：篮子空的情况
        if (boxList.isEmpty()) {
            // 通知男孩摘水果
            this.notify();
            try {
                // 女孩停止吃水果 - 进入等待状态
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return;
        }
        // 情况二：篮子有水果的情况 - 吃水果，把篮子中最后放的水果移除
        Fruit delFruit = boxList.removeLast();

        // 显示信息
        System.out.printf("当前篮子的容量：[%d]，女孩子：[%s]，吃的水果是：[%s] %n", boxList.size(), name, delFruit);

        try {
            // 睡眠 500 毫秒，为了更好地看效果
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
